package com.wtwd.device.controller;


import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.wtwd.device.constant.Constants;
import com.wtwd.device.constant.RespCode;
import com.wtwd.device.model.entity.SysRole;
import com.wtwd.device.model.entity.SysUser;
import com.wtwd.device.model.entity.UpgradeFile;
import com.wtwd.device.model.entity.UpgradeStatement;
import com.wtwd.device.model.vo.RespEntity;
import com.wtwd.device.service.*;
import com.wtwd.device.utils.GetCurrentSysUserInfoUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Api(tags = "升级包管理")
@RestController
@RequestMapping("/upgrade")
public class UpgradeController {


    private final static Logger logger = LoggerFactory.getLogger(UpgradeController.class);
    @Value("${upgrade.file}")
    private String upgradeFile;
    @Value("${file.http}")
    private String fileHttp;
    @Value("${file.path}")
    private String filePath;
    @Autowired
    private DeviceSettingService deviceSettingService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private UpgradeService upgradeService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SysRoleService sysRoleService;

    @Resource
    private GetCurrentSysUserInfoUtils getCurrentSysUserInfoUtils;

    /**
     * 上传升级包
     *
     * @param file
     * @param request
     * @return
     */
    @ApiOperation(value = "上传升级包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "升级包文件", required = true, dataTypeClass = MultipartFile.class)
    })
    @PostMapping("/uploadUpgradeFile")
    public RespEntity uploadUpgradeFile(@RequestBody MultipartFile file, HttpServletRequest request) {
        logger.info("/uploadUpgradeFile");
        String path = filePath.concat(upgradeFile);
        File saveFile = new File(path);
        if (!saveFile.exists()) {
            //文件不存在则创建一个
            saveFile.mkdir();
        }
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString().concat(originalFilename);
        File dest = new File(path.concat(fileName));
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.SUCCESS, fileName);
    }


    /**
     * 添加手表升级包信息
     *
     * @param data
     * @param request
     * @return
     */
    @ApiOperation(value = "添加手表升级包信息", notes = "")
    @DynamicParameters(name = "addUpgradeInfo", properties = {
            @DynamicParameter(name = "watchId", value = "手表id", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "version", value = "固件版本", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "fileType", value = "文件类型", dataTypeClass = Integer.class, required = true),
            @DynamicParameter(name = "filePath", value = "文件上传地址", dataTypeClass = String.class, required = true),
    })
    @PostMapping("/addUpgradeInfo")
    public RespEntity addUpgradeInfo(@RequestBody UpgradeFile data, HttpServletRequest request) {
        logger.info("addUpgradeInfo: data = {}", data.toString());
        //获取用户id
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //判断升级包是否重复
        Integer id = upgradeService.getUpgradeByWatchIdAndVersion(data.getWatchId(), data.getVersion());
        if (id != null) {
            return new RespEntity(RespCode.UPGRADE_REPEAT);
        }
        //判断该用户是否可以操作此手表id
        boolean b = veryIFCanDo(userId, data.getWatchId(), (Integer) list.get(1));
        if (b) {
            data.setUserId(userId);
            data.setUpTime(System.currentTimeMillis());
            data.setUpgradeNum(0);
            //将数据存入数据库中
            Integer i = upgradeService.addUpgradeInfo(data);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);

    }


    /**
     * 查看升级信息列表
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "查看升级信息列表", notes = "")
    @DynamicParameters(name = "getUpgradeInfoList", properties = {
            @DynamicParameter(name = "curPage", value = "当前页", dataTypeClass = Integer.class, required = true),
            @DynamicParameter(name = "pageSize", value = "页面大小", dataTypeClass = Integer.class, required = true),
            @DynamicParameter(name = "watchId", value = "手表id", dataTypeClass = String.class)
    })
    @PostMapping("/getUpgradeInfoList")
    public RespEntity getUpgradeInfoList(@RequestBody JSONObject data, HttpServletRequest request) {
        Integer curPage = (Integer) data.get("curPage");
        Integer pageSize = (Integer) data.get("pageSize");
        String watchId = data.getString("watchId");
        logger.info("/getUpgradeInfoList");
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        if (list == null) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Long userId = (Long) list.get(0);
        Integer roleType = (Integer) list.get(1);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        if (roleType == Constants.SYS_USER_ROLE_TYPE_ADMIN || roleType == Constants.SYS_USER_ROLE_TYPE_OPERATOR) {
            //管理员和运营可以查看所有
            userId = null;
        }
        //查询所有数据
        Map<String, Object> result = upgradeService.getUpgradeInfoList(userId, watchId, curPage, pageSize);
        //拼接保存地址
        ((List<UpgradeFile>) result.get("data")).stream().forEach(e -> {
            String filePath = e.getFilePath();
            e.setFilePath(fileHttp.concat(upgradeFile).concat(filePath));
        });
        return new RespEntity(RespCode.SUCCESS, result);

    }

/*    private Integer id;
    private Integer language;
    private String describe;
    private String watchId;
    private Long createTime;
    private Long updateTime;
    private Integer upgradeId;*/

    /**
     * 添加升级说明
     *
     * @param data
     * @param request
     * @return
     */
    @ApiOperation(value = "添加升级说明", notes = "")
    @DynamicParameters(name = "addUpgradeStatement", properties = {
            @DynamicParameter(name = "language", value = "语言", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "describe", value = "描述", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "watchId", value = "手表id(模型id)", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "upgradeId", value = "升级包id", dataTypeClass = Integer.class, required = true)
    })
    @PostMapping("/addUpgradeStatement")
    public RespEntity addUpgradeStatement(@RequestBody UpgradeStatement data, HttpServletRequest request) {
        logger.info("/addUpgradeStatement: data = {}", data.toString());
        //获取用户id
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //判断升级说明是否重复添加（同一个升级信息下的同一种语言只能有一个升级说明）
        List<Map<String, Object>> upgradeStatementList = upgradeService.getUpgradeStatementListByUpgradeId(data.getUpgradeId());
        upgradeStatementList.stream().forEach(e -> {
            if ((Integer) e.get("language") == data.getLanguage()) {
                data.setLanguage(0);
            }
        });
        if (data.getLanguage() == 0) {
            return new RespEntity(RespCode.LANGUAGE_REPEAT);
        }
        //判断该用户是否可以操作此手表id
        boolean b = veryIFCanDo(userId, data.getWatchId(), (Integer) list.get(1));
        if (b) {
            data.setCreateTime(System.currentTimeMillis());
            data.setUpdateTime(System.currentTimeMillis());
            //将数据存入数据库中
            Integer i = upgradeService.addUpgradeStatement(data);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 编辑升级说明
     *
     * @param data
     * @param request
     * @return
     */
    @ApiOperation(value = "编辑升级说明", notes = "")
    @DynamicParameters(name = "modifyUpgradeStatement", properties = {
            @DynamicParameter(name = "id", value = "升级包id", dataTypeClass = Integer.class, required = true),
            @DynamicParameter(name = "language", value = "语言", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "describe", value = "页面描述", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "watchId", value = "手表id(模型id)", dataTypeClass = String.class, required = true),
            @DynamicParameter(name = "upgradeId", value = "升级包id", dataTypeClass = Integer.class, required = true)
    })
    @PutMapping("/modifyUpgradeStatement")
    public RespEntity modifyUpgradeStatement(@RequestBody UpgradeStatement data, HttpServletRequest request) {
        logger.info("/modifyUpgradeStatement: data = {}", data.toString());
        //获取用户id
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //判断升级说明是否重复添加（同一个升级信息下的同一种语言只能有一个升级说明）
        List<Map<String, Object>> upgradeStatementList = upgradeService.getUpgradeStatementListByUpgradeId(data.getUpgradeId());
        upgradeStatementList.stream().forEach(e -> {
            if ((Integer) e.get("language") == data.getLanguage() && (Integer) e.get("id") != data.getId()) {
                data.setLanguage(0);
            }
        });
        if (data.getLanguage() == 0) {
            return new RespEntity(RespCode.LANGUAGE_REPEAT);
        }
        //判断该用户是否可以操作此手表id
        boolean b = veryIFCanDo(userId, data.getWatchId(), (Integer) list.get(1));
        if (b) {
            data.setUpdateTime(System.currentTimeMillis());
            //修改数据
            Integer i = upgradeService.modifyUpgradeStatement(data);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 根据id删除一条升级说明
     *
     * @param data
     * @param request
     * @return
     */
    @ApiOperation(value = "上传升级包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "升级包文件", required = true, dataTypeClass = MultipartFile.class)
    })
    @PutMapping("/deleteUpgradeStatement")
    public RespEntity deleteUpgradeStatement(@RequestBody UpgradeStatement data, HttpServletRequest request) {
        logger.info("/deleteUpgradeStatement: data = {}", data.toString());
        //获取用户id
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //判断该用户是否可以操作此手表id
        boolean b = veryIFCanDo(userId, data.getWatchId(), (Integer) list.get(1));
        if (b) {
            //删除数据
            Integer i = upgradeService.deleteUpgradeStatement(data.getId(), data.getWatchId());
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 获取升级说明列表
     *
     * @param data
     * @param request
     * @return
     */

    @ApiOperation(value = "根据升级说明列表", notes = "")
    @DynamicParameters(name = "getUpgradeStatementList", properties = {
            @DynamicParameter(name = "id", value = "升级包id", dataTypeClass = Integer.class, required = true),
            @DynamicParameter(name = "watchId", value = "语言", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/getUpgradeStatementList")
    public RespEntity getUpgradeStatementList(@RequestBody UpgradeFile data, HttpServletRequest request) {
        logger.info("/getUpgradeStatementList: upgradeId = {}", data.toString());
        //获取用户id
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //判断该用户是否可以操作此手表id
        boolean b = veryIFCanDo(userId, data.getWatchId(), (Integer) list.get(1));
        if (b) {
            //根据手表id获取升级说明列表
            List<Map<String, Object>> statementList = upgradeService.getUpgradeStatementListByUpgradeId(data.getId());
            return new RespEntity(RespCode.SUCCESS, statementList);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 获取语言下拉框列表
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "获取语言下拉框列表")
    @ApiImplicitParams({
    })
    @GetMapping("/getLanguageList")
    public RespEntity getLanguageList(HttpServletRequest request) {
        logger.info("/getLanguageList");
        List<Map<String, Object>> languageList = upgradeService.getLanguageList();
        return new RespEntity(RespCode.SUCCESS, languageList);
    }

    /**
     * 模糊查询获取手表id
     *
     * @param request
     * @return
     */

    @ApiOperation(value = "模糊查询获取手表id")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "key", value = "手表模型id", required = true, dataTypeClass = String.class)
    })
    @GetMapping("/getWatchIdList")
    public RespEntity getWatchIdList(@RequestParam("key") String key, HttpServletRequest request) {
        logger.info("/getWatchIdList");
        List<Object> list = getUserIdAndRoleType(request);
        if (list == null) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer roleType = (Integer) list.get(1);
        Long userId = (Long) list.get(0);
        if (roleType == Constants.SYS_USER_ROLE_TYPE_ADMIN || roleType == Constants.SYS_USER_ROLE_TYPE_OPERATOR) {
            userId = null;
        }
        List<String> watchIdList = upgradeService.getWatchIdList(key, userId);
        return new RespEntity(RespCode.SUCCESS, watchIdList);
    }

    /**
     * 获取用户id和角色类型
     *
     * @return
     */
    public List<Object> getUserIdAndRoleType(HttpServletRequest request) {
        String token = request.getHeader("Manager-token");
        Map<String, Object> map = redisService.getUserInfoByToken(token);
        if (map == null || map.get("user") == null) {
            return null;
        }
        String str = (String) map.get("user");
        SysUser user = JSONObject.parseObject(str, SysUser.class);
        //根据角色id获取角色类型
        SysRole sysRole = sysRoleService.getSysRoleByRoleId(user.getRoleId());
        Long userId = user.getUserId();
        Integer roleType = sysRole.getRoleType();
        List<Object> list = new ArrayList<>();
        list.add(0, userId);
        list.add(1, roleType);
    /*    List<Object> list = new ArrayList<>();

        list.add(0,4l);

        list.add(1,1);*/
        return list;
    }


    /**
     * 判断该用户是否有权限操作该手表设置
     *
     * @param userId
     * @param watchId
     * @return
     */
    public boolean veryIFCanDo(Long userId, String watchId, Integer roleType) {
        if (roleType == Constants.SYS_USER_ROLE_TYPE_ADMIN || roleType == Constants.SYS_USER_ROLE_TYPE_OPERATOR) {
            return true;
        }
        //根据用户id查找该用户所属客户下的所有手表id
        List<String> watchIdList = deviceSettingService.getWatchIdByUserId(userId);
        boolean b = watchIdList.contains(watchId);
        return b;
    }


    @ApiOperation(value = "删除升级包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "记录ID", required = true, dataType = "int")
            , @ApiImplicitParam(name = "watchId", value = "手表ID", required = true, dataType = "string")
    })
    @PostMapping("/deleteUpgrade")
    public RespEntity deleteUpgrade(@RequestParam Integer id,@RequestParam String watchId, HttpServletRequest request) {
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //判断该用户是否可以操作此手表id
        boolean b = veryIFCanDo(userId, watchId, (Integer) list.get(1));
        if (b) {
            //删除数据
            Integer i = upgradeService.deleteUpgrade(id);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


}

